package com.example.jsoup.kuang.question.utilsPlus;

/**
 * Created by HMF on 2021/10/15 10:29
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.jsoup.kuang.question.utils.NeedDetailUtil;
import com.example.jsoup.kuang.question.utils.NeedListUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 问题库 页面详细数据 列表
 */
public class QuestionBankPageDetailDataListUtil {

    public static void main(String[] args) throws Exception {
        String strJson = QuestionBankPageDetailDataListUtil.getPageDetailListReturnString(2, 1);

        System.out.println("\n\n页面爬取的数据字符串 json::::::\n" + strJson);
    }

    //////////////////////////////////////  NeedListUtil (1) start //////////////////////////////////////

    /**
     * @param demand_type 【---人才需求 demand_type=1---】、【---技术需求 demand_type=2---】、【---服务需求 demand_type=3---】
     * @param pageIndex   【---页码 从 1 开始，需要循环递增 1，来获取下一页的数据---】
     * @return 每一页的需求列表数据 这里 返回 15 条数据
     */
    public static List<Map<String, String>> getNeedListReturnMapList(int demand_type, int pageIndex) {
        // demand_type 只能为 1、2、3，不是其中之一时，返回 null
        if (demand_type == 1 || demand_type == 2 || demand_type == 3) {
//            String addressUrl = "https://www.kczg.org.cn/index/ajaxGetDemand?demand_type=1&industry_id=1&field_id=1&date_type=0&title=0&province_id=0&first_code=0&size_type=2&page=";
            String addressUrl = "https://www.kczg.org.cn/index/ajaxGetDemand?demand_type=" + demand_type + "&industry_id=" + demand_type + "&field_id=" + demand_type + "&date_type=0&title=0&province_id=0&first_code=0&size_type=2&page=";

            List<Map<String, String>> idAndUrlMapList = new ArrayList<>();

            // 创建Httpclient对象
            CloseableHttpClient httpClient = HttpClients.createDefault();

            // 问题库 技术需求 列表数据
            HttpPost httpPost = new HttpPost(addressUrl + pageIndex);

            // 请求头 user-agent
            httpPost.addHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.366");

            // 响应
            CloseableHttpResponse response = null;

            try {
                // 使用httpClient发起请求 获取 response
                response = httpClient.execute(httpPost);

                // 解析响应
                if (response.getStatusLine().getStatusCode() == 200) {

                    // 响应返回的json数据，但这里是String字符串类型，所以下面要做转换
                    String content = EntityUtils.toString(response.getEntity(), "utf8");

                    /////////////// 返回的 content json字符串解析 ////////////

                    // 把字符串转换为 json 对象
                    JSONObject jsonObject = JSON.parseObject(content);

                    // 通过已知的 key 键，获取 value 值
                    String data = jsonObject.get("data").toString(); // data 列表字符串

                    // 把 data 字符串列表 转为 类似 List 类型的数组
                    JSONArray jsonArray = new JSONArray(data);  // 使用这个包的 import org.json.JSONArray;

                    for (int i = 0; i < jsonArray.length(); i++) {
                        Map<String, String> map = new HashMap<>();

                        String id = jsonArray.getJSONObject(i).get("id").toString();
                        String url = jsonArray.getJSONObject(i).get("url").toString();

                        map.put("id", id);
                        map.put("url", url);

                        idAndUrlMapList.add(map);
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {

                try {
                    // 关闭httpClient
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    // 关闭response
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // 返回结果列表
            return idAndUrlMapList;

        } else {  // demand_type 不是 1、2、3 其中一个时，返回 null
            return null;
        }
    }
    //////////////////////////////////////  NeedListUtil (1) end //////////////////////////////////////


    //////////////////////////////////////  NeedDetailUtil (2) start //////////////////////////////////////

    /**
     * @param idAndUrl 【上一个方法传进来的 Map 类型数据，包括了 id 和 url
     * @param type     【(技术需求详情 type=1)、（服务需求详情 type=2)】
     * @return 返回页面的信息数据，通过 key 值取出来
     * @throws Exception
     */
    public static Map<String, String> getTechnologyAndServiceNeedDetail(Map<String, String> idAndUrl, int type) throws Exception {

        Map<String, String> pageDataMap = new HashMap<>();

        // 直接添加原id original_id 和 type 到 返回的 Map 中
        pageDataMap.put("original_id", idAndUrl.get("id"));
        pageDataMap.put("type", type + "");

        // 联系人 和 联系电话 没有数据可爬取，在这里也直接设置
        pageDataMap.put("contacts_member", "");
        pageDataMap.put("contacts_mobile", "");

//        int type = 0;  // 直接从入参中传入

        // 需要爬取并且入库的内容 title、base、msg
        // title
        String need_name = ""; // 需求名称
        String send_time = ""; // 发布时间
        String source = ""; // 来源
        String money = ""; // 预算
        int money_flag = 0; // 是否双方协商  0：否、1：是

        // base
        String industry_category = ""; // 行业分类
        String area = ""; // 地区
        String demand_side = ""; // 需求方

        // msg
        // type = 1
        String background_content = ""; // 需求背景
        String problem_content = ""; // 需解决的主要技术难题
        String goal_content = ""; // 拟实现的主要技术目标/具体指标

        // type = 2
        String describe_content = ""; // 需求描述


        // 请求的页面地址
        String url = "https://www.kczg.org.cn" + idAndUrl.get("url");

        // 解析返回的html页面，生成 Document 对象
        Document document = Jsoup.parse(new URL(url), 5000);


        // 需要爬取内容的外层 div
        Element parent_div = document.getElementsByClass("detail-con").first();

        /**
         * title标题 div
         */
        Element div_title = parent_div.getElementsByClass("title").first();

        // 需求名称
        need_name = div_title.getElementsByClass("title-label").text();
        pageDataMap.put("need_name", need_name);

        // 发布时间
        send_time = div_title.getElementsByClass("fl").get(0).text().split(":")[1].trim();
        pageDataMap.put("send_time", send_time);

        // 来源
        source = div_title.getElementsByClass("fl").get(1).text().split(":")[1].trim();
        pageDataMap.put("source", source);

        // 预算
//        money = div_title.getElementsByClass("money").first().getElementsByTag("span").text().replace("万", "");
//        money = div_title.getElementsByClass("money").first().getElementsByTag("span").text();
//        money = div_title.getElementsByClass("money").first().getElementsByTag("span").text().split("万")[0];

        String money_text = div_title.getElementsByClass("money").first().getElementsByTag("span").text().trim();

        if (money_text.equals("双方协商")) {
            money = "";
            money_flag = 1;

            pageDataMap.put("money", money);
            pageDataMap.put("money_flag", money_flag + "");

        } else { // 说明有 万 字
            String[] str = money_text.split("万");
            money = str[0]; // 取前面的 数字 ，如原来是 500万，这里就取了 500
            money_flag = 0;

            pageDataMap.put("money", money);
            pageDataMap.put("money_flag", money_flag + "");
        }

        /**
         * base基本信息base div
         */
        Element div_base = parent_div.getElementsByClass("base").first();

        Elements p_list = div_base.getElementsByClass("base-detail").first().getElementsByTag("p");

        industry_category = p_list.get(0).getElementsByTag("span").text();
        area = p_list.get(1).getElementsByTag("span").text();
        demand_side = p_list.get(2).getElementsByTag("span").text();

        pageDataMap.put("industry_category", industry_category);
        pageDataMap.put("area", area);
        pageDataMap.put("demand_side", demand_side);

        /**
         * msg详细信息 div_msg 列表
         */
        Elements div_msg_list = parent_div.getElementsByClass("msg");

        // 技术需求详情 type=1
        // 服务需求详情 type=2
        if (type == 1) {
            String backgroundTitle = "需求背景";
            String problemTitle = "需解决的主要技术难题";
            String goalTitle = "拟实现的主要技术目标/具体指标";

            for (int i = 0; i < div_msg_list.size(); i++) {
                String msg_html = div_msg_list.get(i).html();
                String contentTitle = div_msg_list.get(i).getElementsByClass("msg-label").text();

                // 通过判断知道具体少了哪一项，并存储到对应的字段中
                if (contentTitle.equals(backgroundTitle)) {
                    background_content = msg_html;
                } else if (contentTitle.equals(problemTitle)) {
                    problem_content = msg_html;
                } else if (contentTitle.equals(goalTitle)) {
                    goal_content = msg_html;
                } else {
                    // 不处理
                }
            }

        } else if (type == 2) {
            describe_content = div_msg_list.get(0).html();

        } else {
            // 不处理
            return null;
        }

        pageDataMap.put("background_content", background_content);
        pageDataMap.put("problem_content", problem_content);
        pageDataMap.put("goal_content", goal_content);

        pageDataMap.put("describe_content", describe_content);

        return pageDataMap;
    }


    /**
     * 人才需求，因为页面的结构不同，所以要另外起一个方法
     *
     * @param idAndUrl
     */
    public static Map<String, String> getTalentNeedDetail(Map<String, String> idAndUrl) throws Exception {

        Map<String, String> pageDataMap = new HashMap<>();

        // 直接添加原id original_id 到 返回的 Map 中
        pageDataMap.put("original_id", idAndUrl.get("id"));

        // 联系人 和 联系电话 没有数据可爬取，在这里也直接设置
        pageDataMap.put("contacts_member", "");
        pageDataMap.put("contacts_mobile", "");

        String need_name = "";  // 职位需求名称
        String send_time = "";  // 发布时间
        String money = ""; // 预算
        int pay_type = 1; // 默认为 1，按月支付，双方协商也是为 1

        String area = ""; // 地区
        String experience = "";  // 工作经验
        String degree = ""; // 个人学历
        String direction = ""; // 研究方向
        String industry_category = ""; // 行业领域

        String describe_content = ""; // 需求描述

        // 请求的页面地址
        String url = "https://www.kczg.org.cn" + idAndUrl.get("url");

        // 解析返回的html页面，生成 Document 对象
        Document document = Jsoup.parse(new URL(url), 5000);

        // 需要爬取内容的外层 div
        Element parent_div = document.getElementsByClass("detail-con").first();

        /**
         * title div 层
         */
        Element div_title = parent_div.getElementsByClass("title").first();

        // 职位需求名称
        need_name = div_title.getElementsByClass("title-label").text().trim();
        pageDataMap.put("need_name", need_name);

        // 发布时间
        send_time = div_title.getElementsByClass("time").text().split(":")[1].trim() + " 00:00:00";
        pageDataMap.put("send_time", send_time);

        // 预算
        String money_text = div_title.getElementsByClass("money").first().text().trim();

        // 判断是否有 年 字，即可，以为其他情况都为 1
        if (money_text.contains("年")) { // 字符串有 年 字
            pay_type = 2;
        } else {
            pay_type = 1;
        }
        pageDataMap.put("pay_type", pay_type + "");

        money = div_title.getElementsByClass("mr").first().text().trim();
        pageDataMap.put("money", money);

        /**
         * base div 层
         */
        Element div_base = parent_div.getElementsByClass("base").first();

        //
        String p_text = div_base.getElementsByClass("base-detail").first().getElementsByTag("p").text();

        String[] p_text_list = p_text.split("\\|");  // 这里的正则表达式有点意思

        area = p_text_list[0].trim();
        pageDataMap.put("area", area);

        experience = p_text_list[1].trim();
        pageDataMap.put("experience", experience);

        degree = p_text_list[2].trim();
        pageDataMap.put("degree", degree);

        direction = p_text_list[3].trim();
        pageDataMap.put("direction", direction);

        industry_category = p_text_list[4].trim();
        pageDataMap.put("industry_category", industry_category);

        /**
         * msg div 层
         */
        Element div_msg = parent_div.getElementsByClass("msg").first();

        describe_content = div_msg.html();
        pageDataMap.put("describe_content", describe_content);

        return pageDataMap;
    }
    //////////////////////////////////////  NeedDetailUtil (2) end //////////////////////////////////////


    /////////////////////////  NeedListUtil 和 NeedDetailUtil 结合 (3) start //////////////////////////////////////

    /**
     * 爬取列表的每一页详细数据
     *
     * @param demand_type 【---人才需求 demand_type=1---】、【---技术需求 demand_type=2---】、【---服务需求 demand_type=3---】
     * @param pageIndex   【---页码 从 1 开始，需要循环递增 1，来获取下一页的数据---】
     * @return 返回 Json 格式的 详情页数据 列表 字符串 返回 15 条数据
     * @throws Exception
     */
    public static String getPageDetailListReturnString(int demand_type, int pageIndex) throws Exception {

        List<Map<String, String>> pageDetailDataList = new ArrayList<>();

        // 列表 每个元素 包含 id 和 url
//        List<Map<String, String>> idAndUrlList = NeedListUtil.getNeedListReturnMapList(3, 1);
        List<Map<String, String>> idAndUrlList = NeedListUtil.getNeedListReturnMapList(demand_type, pageIndex);


        if (demand_type == 1) { /////////// 人才需求  ///////////

            for (Map<String, String> idAndUrl : idAndUrlList) {
                // 这里返回的就是每页的详细数据
                Map<String, String> needDetail = QuestionBankPageDetailDataListUtil.getTalentNeedDetail(idAndUrl);
                pageDetailDataList.add(needDetail);
            }

        } else if (demand_type == 2) {  //////////// 技术需求  ///////////

            for (Map<String, String> idAndUrl : idAndUrlList) {
                // 这里返回的就是每页的详细数据
                Map<String, String> needDetail = NeedDetailUtil.getTechnologyAndServiceNeedDetail(idAndUrl, 1);
                pageDetailDataList.add(needDetail);
            }

        } else if (demand_type == 3) { //////////// 服务需求  ///////////

            for (Map<String, String> idAndUrl : idAndUrlList) {
                // 这里返回的就是每页的详细数据
                Map<String, String> needDetail = NeedDetailUtil.getTechnologyAndServiceNeedDetail(idAndUrl, 2);
                pageDetailDataList.add(needDetail);
            }
        }

        return JSONObject.toJSON(pageDetailDataList).toString();
    }

    /**
     * 爬取列表的每一页详细数据
     *
     * @param demand_type 【---人才需求 demand_type=1---】、【---技术需求 demand_type=2---】、【---服务需求 demand_type=3---】
     * @param pageIndex   【---页码 从 1 开始，需要循环递增1传入该值，获取下一页的数据---】
     * @return 返回 List 格式的 详情页数据 列表 数据
     * @throws Exception
     */
    public static List<Map<String, String>> getPageDetailListReturnList(int demand_type, int pageIndex) throws Exception {

        List<Map<String, String>> pageDetailDataList = new ArrayList<>();

        // 列表 每个元素 包含 id 和 url
//        List<Map<String, String>> idAndUrlList = NeedListUtil.getNeedListReturnMapList(3, 1);
        List<Map<String, String>> idAndUrlList = NeedListUtil.getNeedListReturnMapList(demand_type, pageIndex);


        if (demand_type == 1) { /////////// 人才需求  ///////////

            for (Map<String, String> idAndUrl : idAndUrlList) {
                // 这里返回的就是每页的详细数据
                Map<String, String> needDetail = QuestionBankPageDetailDataListUtil.getTalentNeedDetail(idAndUrl);
                pageDetailDataList.add(needDetail);
            }

        } else if (demand_type == 2) {  //////////// 技术需求  ///////////

            for (Map<String, String> idAndUrl : idAndUrlList) {
                // 这里返回的就是每页的详细数据
                Map<String, String> needDetail = NeedDetailUtil.getTechnologyAndServiceNeedDetail(idAndUrl, 1);
                pageDetailDataList.add(needDetail);
            }

        } else if (demand_type == 3) { //////////// 服务需求  ///////////

            for (Map<String, String> idAndUrl : idAndUrlList) {
                // 这里返回的就是每页的详细数据
                Map<String, String> needDetail = NeedDetailUtil.getTechnologyAndServiceNeedDetail(idAndUrl, 2);
                pageDetailDataList.add(needDetail);
            }
        }

        return pageDetailDataList;
    }

    /////////////////////////  NeedListUtil 和 NeedDetailUtil 结合(3) end //////////////////////////////////////
}
